/*
工厂方法模式（Factory Method Pattern）是一种创建型设计模式，它定义了一个用于创建对象的接口，但将具体的对象创建延迟到子类中。
这样可以将对象的创建与使用解耦，使得代码更加灵活和可扩展。

工厂方法模式的核心思想是将对象的创建委托给子类，子类根据具体的需求来创建对象。
这样，当需要创建不同类型的对象时，只需要添加新的子类即可，而不需要修改已有的代码。

以下是一个使用工厂方法模式实现的C语言例程：
*/

#include <stdio.h>
#include <stdlib.h>

// 抽象产品接口
typedef struct
{
    void (*printInfo)();
} Product;

// 具体产品A
typedef struct
{
    Product product;
    int value;
} ConcreteProductA;

// 具体产品A的打印方法
void printInfoA(ConcreteProductA *product)
{
    printf("Concrete Product A: %d\n", product->value);
}

// 具体产品B
typedef struct
{
    Product product;
    char *name;
} ConcreteProductB;

// 具体产品B的打印方法
void printInfoB(ConcreteProductB *product)
{
    printf("Concrete Product B: %s\n", product->name);
}

// 抽象工厂接口
typedef struct
{
    Product *(*createProduct)();
} Factory;

// 具体工厂A
typedef struct
{
    Factory factory;
} ConcreteFactoryA;

// 具体工厂A的创建具体产品A的方法
Product *createProductA()
{
    ConcreteProductA *product = (ConcreteProductA *)malloc(sizeof(ConcreteProductA));
    product->product.printInfo = printInfoA;
    product->value = 10;
    return (Product *)product;
}

// 具体工厂B
typedef struct
{
    Factory factory;
} ConcreteFactoryB;

// 具体工厂B的创建具体产品B的方法
Product *createProductB()
{
    ConcreteProductB *product = (ConcreteProductB *)malloc(sizeof(ConcreteProductB));
    product->product.printInfo = printInfoB;
    product->name = "Product B";
    return (Product *)product;
}

int main()
{
    // 使用具体工厂A创建产品A
    Factory *factoryA = (Factory *)malloc(sizeof(ConcreteFactoryA));
    factoryA->createProduct = createProductA;
    Product *productA = factoryA->createProduct();
    productA->printInfo(productA); // 输出结果为 "Concrete Product A: 10"

    // 使用具体工厂B创建产品B
    Factory *factoryB = (Factory *)malloc(sizeof(ConcreteFactoryB));
    factoryB->createProduct = createProductB;
    Product *productB = factoryB->createProduct();
    productB->printInfo(productB); // 输出结果为 "Concrete Product B: Product B"

    return 0;
}

/*
在上面的例程中，定义了一个抽象产品接口Product，以及两个具体产品ConcreteProductA和ConcreteProductB，它们都实现了printInfo方法。
接着定义了一个抽象工厂接口Factory，以及两个具体工厂ConcreteFactoryA和ConcreteFactoryB，它们都实现了createProduct方法。

在main函数中，首先使用具体工厂A创建产品A，然后调用产品A的printInfo方法来输出信息。
接着使用具体工厂B创建产品B，并调用产品B的printInfo方法来输出信息。
由于具体产品和具体工厂都实现了抽象接口，所以可以通过抽象接口来引用具体对象，实现了对具体对象的解耦。

工厂方法模式可以帮助我们实现对象的创建和使用的分离，提供了更好的灵活性和可扩展性。
当需要添加新的产品类型时，只需要创建对应的具体产品和具体工厂，并实现相应的创建方法即可，而不需要修改已有的代码。
*/